package com.pointi.emoClientM;

import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;

import com.pointi.emoTools.WorkList;
import com.pointi.emoTools.emoLogManager;

public class ThreadWorkManager extends Thread
{
	private ConcurrentLinkedQueue<ThreadWorkManager> _WorkManager ;
	private ConfigurationData conf_data ;
	private JDBC jdbc ;

	private CheckStatus _Status ;
	private ArrayList<WorkList> _WorkList ;
	private String _ClientNo ;
	private int workerLimit ;
	private int workerCount ;

	public ThreadWorkManager(ConcurrentLinkedQueue<ThreadWorkManager> inWorkManager)
	{
		_WorkManager = inWorkManager ;
		_WorkList = null ;
		_ClientNo = "" ;
		workerLimit = 0 ;
		workerCount = 0 ;
	}

	public void start(ConfigurationData inConfData, JDBC inJDBC, ArrayList<WorkList> inWorkList, CheckStatus inStatus)
	{
		_WorkManager.add(this) ;
		_WorkList = inWorkList ;
		_Status = inStatus ;
		_ClientNo = _Status.fnGetClientNo() ;
		conf_data = inConfData ;
		jdbc = inJDBC ;
		super.start() ;
	}

	public void run()
	{
		System.out.println("[WorkManager] Managing ..") ;

		ArrayList<String> RCL = new ArrayList<String>() ; // Recent Callkey List
		ConcurrentLinkedQueue<ThreadTCPClient> _TCPClient = new ConcurrentLinkedQueue<ThreadTCPClient>() ;

		try
		{
			workerLimit = Integer.valueOf(conf_data.s_worker_limit) ;
			boolean loopHandlerB = true ;
			while(loopHandlerB)
			{
				// ____________________________________________________________________________________________________
				// Get Work Schedule Info. | t_work_scheduler

				if(_WorkList.size() == 0)
				{
					jdbc.fnGetWorkScheduleForClient(_ClientNo, _WorkList) ;
					emoLogManager.mLog("Get Work List Size : " + _WorkList.size()) ;
					
					// ____________________________________________________________________________________________________
					// Check Work Condition & Server Status & Start Working

					int checkLimit = _WorkList.size() ;
					for (int i=0; i<checkLimit; i++)
					{
						WorkList mWork = _WorkList.get(0) ;
						_WorkList.remove(0) ;
						if (jdbc.fnIsWorkAvailable(mWork._CallKey) && !RCL.contains(mWork._CallKey))
						{
							if (jdbc.fnIsServerAlive(mWork._ServerNo))
							{
								if (_TCPClient.isEmpty()) { _TCPClient = new ConcurrentLinkedQueue<ThreadTCPClient>() ; }
								workerCount = _TCPClient.size() ;
								if (workerCount < workerLimit)
								{
									RCL.add(mWork._CallKey) ;
									new ThreadTCPClient(_TCPClient).start(jdbc, mWork, RCL) ;
									_Status.fnSetClientCount(_TCPClient.size()) ;
								}
							}
							else
							{
								System.out.println("[WorkManager] Reassign Server !") ;
								jdbc.fnReassignServer(mWork._Seq, mWork._ClientNo) ;
							}
						}
						else { emoLogManager.mLog("[SKIP] Using .. : " + mWork._Seq) ; }
					}
				}
				Thread.sleep(1000) ;
				System.out.println(String.format("[CLT][Working] %d(%d) of %d", _TCPClient.size(), RCL.size(), workerLimit)) ;
			}
		}
		catch (Exception e) { e.printStackTrace() ; }
		_WorkManager.remove(this) ;
	}
}
